// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//
#pragma once

#include <stdlib.h>
#include <string>

#define fprintf(...)

#include <kmsql/postgre/definitions.h>

#include <kmsql/postgre/nodes/list.h>
#include <kmsql/postgre/nodes/parse_nodes.h>

namespace kmsql::pg {
    typedef struct parse_result_str parse_result;

    struct parse_result_str {
        bool success;
        PGList *parse_tree;
        std::string error_message;
        int error_location;
    };

    void pg_parser_init();

    void pg_parser_parse(const char *query, parse_result *res);

    void pg_parser_cleanup();

    // error handling
    int ereport(int code, ...);

    void elog(int code, const char *fmt, ...);

    int errcode(int sqlerrcode);

    int errmsg(const char *fmt, ...);

    int errhint(const char *msg);

    int errmsg_internal(const char *fmt, ...);

    int errdetail(const char *fmt, ...);

    int errposition(int cursorpos);

    char *psprintf(const char *fmt, ...);

    // memory mgmt
    char *pstrdup(const char *in);

    void *palloc(size_t n);

    void pfree(void *ptr);

    void *palloc0fast(size_t n);

    void *repalloc(void *ptr, size_t n);

    char *NameListToString(PGList *names);

    void *copyObject(const void *from);

    bool equal(const void *a, const void *b);

    int exprLocation(const PGNode *expr);

    // string gunk
    int pg_database_encoding_max_length(void);

    bool pg_verifymbstr(const char *mbstr, int len, bool noError);

    int pg_mbstrlen_with_len(const char *mbstr, int len);

    int pg_mbcliplen(const char *mbstr, int len, int limit);

    int pg_mblen(const char *mbstr);

    PGDefElem *defWithOids(bool value);

    typedef unsigned int pg_wchar;

    unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
}
